package jzoffer;

import leetcode.tree.TreeNode;

import java.util.HashMap;
import java.util.Map;

/**
 * 输入某二叉树的前序遍历和中序遍历的结果，请重建出该二叉树。
 * 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
 * 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}，则重建二叉树并返回。
 */
public class ReConstructBinaryTree {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if (preorder == null || preorder.length == 0) {
            return null;
        }
        int cap = (int) ((inorder.length / 0.75) + 1);
        Map<Integer, Integer> map = new HashMap<>(cap);
        for (int i = 0; i < inorder.length; i++) {
            map.put(inorder[i], i);
        }
        return buildTree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1, map);
    }

    private TreeNode buildTree(int[] preorder, int preorderStart, int preOrderEnd, int[] inorder, int inOrderStart, int inOrderEnd, Map<Integer, Integer> map) {
        if (preorderStart > preOrderEnd) {
            return null;
        }
        int rootVal = preorder[preorderStart];
        TreeNode root = new TreeNode(rootVal);
        if (preorderStart == preOrderEnd) {
            return root;
        } else {
            Integer rootIndex = map.get(rootVal);
            int leftNodeCount = rootIndex - inOrderStart;
            int rightNodeCount = inOrderEnd - rootIndex;
            //左子树，第一个节点为根节点，因此要+1，
            root.left = buildTree(preorder, preorderStart + 1, preorderStart + leftNodeCount, inorder, inOrderStart, rootIndex - 1, map);
            root.right = buildTree(preorder, preOrderEnd - rightNodeCount + 1, preOrderEnd, inorder, rootIndex + 1, inOrderEnd, map);

            return root;
        }


    }
}
